package sys_user_service

import (
	"database/sql"
	"errors"
	"fmt"
	"gf-admin/app/dao/sys/sys_dept_dao"
	"gf-admin/app/dao/sys/sys_user_dao"
	"gf-admin/app/dao/sys/sys_user_post_dao"
	"gf-admin/app/pojo/sys/sys_dept"
	"gf-admin/app/pojo/sys/sys_post"
	"gf-admin/app/pojo/sys/sys_role"
	"gf-admin/app/pojo/sys/sys_user"
	"gf-admin/app/service/casbin_adapter_service"
	"gf-admin/app/service/sys/sys_dept_service"
	"gf-admin/app/service/sys/sys_role_service"
	"gf-admin/app/service/sys/sys_user_post_service"
	"gf-admin/boot"
	"gf-admin/library/service"
	"gf-admin/library/utils"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/text/gstr"
	"github.com/gogf/gf/util/gconv"
)

type EditParams struct {
	Id           int    `p:"id" v:"required#用户id不能为空"`
	UserNickname string `p:"user_nickname" v:"required#用户昵称不能为空" orm:"user_nickname"` // 用户昵称
	Mobile       string `p:"mobile" v:"required|phone#手机号不能为空|手机号格式错误" orm:"mobile,unique"`
	UserEmail    string `p:"user_email" v:"email#邮箱格式错误" orm:"user_email"`
	Sex          int    `p:"sex" orm:"sex"`
}

type UpdatePwdReq struct {
	OldPassword string `p:"oldPassword" v:"required#旧密码不能为空"`
	NewPassword string `p:"newPassword" v:"required#新密码不能为空"`
}

/**
修改密码
*/
func UpdatePwd(r *ghttp.Request, data *UpdatePwdReq) error {

	currentUser, err := GetCurrentUserInfo(r)

	if err != nil {
		return err
	}

	OldPassword := utils.EncryptCBC(gconv.String(data.OldPassword), utils.AdminCbcPublicKey)

	if OldPassword != currentUser["user_password"].(string) {
		return errors.New("原始密码错误!")
	}

	return ResetUserPwd(&sys_user.ResetPwdReq{
		Id:       gconv.Uint64(currentUser["id"]),
		Password: data.NewPassword,
	})
}

/**
用户中心修改用户信息
*/
func Edit(info *EditParams) (sql.Result, error) {
	return sys_user.Model.Where("id", info.Id).Data(info).Update()
}

// 获取单前登录用户的信息
func GetCurrentUserInfo(r *ghttp.Request) (map[string]interface{}, error) {
	id := GetLoginID(r)
	userEntity, err := sys_user_dao.GetUserById(id)
	if err != nil {
		return nil, err
	}
	userInfo := gconv.Map(userEntity)
	//delete(userInfo, "user_password")
	userInfo["roles"] = make([]string, 0)
	userInfo["posts"] = new([]*sys_post.Entity)
	userInfo["dept_info"] = nil
	allRoles, err := sys_role_service.GetRoleList()
	if err != nil {
		return nil, err
	}
	roles, err := GetAdminRole(userEntity.Id, allRoles)
	if err != nil {
		return nil, err
	}
	//角色
	userInfo["roles"] = roles
	//岗位
	posts, err := GetPostsByUserId(userEntity.Id)
	if err != nil {
		return nil, err
	}
	userInfo["posts"] = posts
	//部门
	if dept_info, err := sys_dept_service.GetDeptById(userEntity.DeptId); err != nil {
		return nil, err
	} else {
		userInfo["dept_info"] = dept_info
	}

	return userInfo, nil

}

func GetPostsByUserId(id uint64) ([]*sys_post.Entity, error) {
	return sys_user_post_service.GetPostsByUserId(id)
}

//获取登陆用户ID
func GetLoginID(r *ghttp.Request) (userId uint64) {
	userInfo := GetLoginAdminInfo(r)
	if userInfo != nil {
		userId = userInfo.Id
	}
	return
}

//获取缓存的用户信息
func GetLoginAdminInfo(r *ghttp.Request) (userInfo *sys_user.Entity) {
	resp := boot.AdminGfToken.GetTokenData(r)
	gconv.Struct(resp.Get("data"), &userInfo)
	return
}

//获取当前登录用户信息，直接从数据库获取
func GetCurrentUser(r *ghttp.Request) (userInfo *sys_user.Entity, err error) {
	id := GetLoginID(r)
	userInfo, err = sys_user_dao.GetUserById(id)
	return
}

//获取管理员列表
func GetAdminList(req *sys_user.SearchReq) (total, page int, userList []*sys_user.Entity, err error) {
	if req.PageSize == 0 {
		req.PageSize = service.AdminPageNum
	}
	var depts []*sys_dept.Dept
	if req.DeptId != "" {
		depts, err = sys_dept_dao.GetList(&sys_dept.SearchParams{Status: "1"})
		if err != nil {
			g.Log().Error(err)
			err = gerror.New("获取部门信息失败")
			return
		}
		mDepts := gconv.SliceMap(depts)
		deptId := gconv.Int(req.DeptId)
		req.DeptIds = append(req.DeptIds, deptId)
		childrenIds := utils.FindSonByParentId(mDepts, deptId, "parentId", "deptId")
		for _, d := range childrenIds {
			req.DeptIds = append(req.DeptIds, gconv.Int(d["deptId"]))
		}
	}
	return sys_user_dao.GetAdminList(req)
}

//获取管理员的角色信息
func GetAdminRole(userId uint64, allRoleList []*sys_role.Entity) (roles []*sys_role.Entity, err error) {
	roleIds, err := GetAdminRoleIds(userId)
	if err != nil {
		return
	}
	roles = make([]*sys_role.Entity, 0, len(allRoleList))
	for _, v := range allRoleList {
		for _, id := range roleIds {
			if id == v.Id {
				roles = append(roles, v)
			}
		}
		if len(roles) == len(roleIds) {
			break
		}
	}
	return
}

//获取管理员对应的角色ids
func GetAdminRoleIds(userId uint64) (roleIds []uint, err error) {
	enforcer, e := casbin_adapter_service.GetEnforcer()
	if e != nil {
		err = e
		return
	}
	//查询关联角色规则
	groupPolicy := enforcer.GetFilteredGroupingPolicy(0, fmt.Sprintf("u_%d", userId))
	if len(groupPolicy) > 0 {
		roleIds = make([]uint, len(groupPolicy))
		//得到角色id的切片
		for k, v := range groupPolicy {
			roleIds[k] = gconv.Uint(gstr.SubStr(v[1], 2))
		}
	}
	return
}

func GetAdminPosts(userId uint64) (postIds []int64, err error) {
	return sys_user_post_dao.GetAdminPosts(userId)
}

func ChangeUserStatus(req *sys_user.StatusReq) error {
	return sys_user_dao.ChangeUserStatus(req)
}

func ResetUserPwd(req *sys_user.ResetPwdReq) error {
	//密码加密
	req.Password = utils.EncryptCBC(gconv.String(req.Password), utils.AdminCbcPublicKey)
	return sys_user_dao.ResetUserPwd(req)
}

//添加管理员操作
func AddUser(req *sys_user.AddUserReq) (InsertId int64, err error) {
	//密码加密
	req.Password = utils.EncryptCBC(gconv.String(req.Password), utils.AdminCbcPublicKey)
	return sys_user_dao.Add(req)
}

//修改用户信息
func EditUser(req *sys_user.EditUserReq) (err error) {
	return sys_user_dao.Edit(req)
}